
#include "stdafx.h"
#include "MeshModel.h"
#include <wrap/io_trimesh/io_mask.h>
using namespace vcg;


/*

//This member returns the information of the Mesh in terms of VC,VQ,FC,FQ,WT
//where:
//VC = VertColor,VQ = VertQuality,FC = FaceColor,FQ = FaceQuality,WT = WedgTexCoord

QString GLArea::GetMeshInfoString()
{
	QString info;
	if(mm()->hasDataMask(MeshModel::MM_VERTQUALITY) ) {info.append("VQ ");}
	if(mm()->hasDataMask(MeshModel::MM_VERTCOLOR) )   {info.append("VC ");}
	if(mm()->hasDataMask(MeshModel::MM_VERTRADIUS) )  {info.append("VR ");}
	if(mm()->hasDataMask(MeshModel::MM_VERTTEXCOORD)) {info.append("VT ");}
	if(mm()->hasDataMask(MeshModel::MM_VERTCURV) )    {info.append("VK ");}
	if(mm()->hasDataMask(MeshModel::MM_VERTCURVDIR) ) {info.append("VD ");}
	if(mm()->hasDataMask(MeshModel::MM_FACECOLOR) )   {info.append("FC ");}
	if(mm()->hasDataMask(MeshModel::MM_FACEQUALITY) ) {info.append("FQ ");}
	if(mm()->hasDataMask(MeshModel::MM_WEDGTEXCOORD)) {info.append("WT ");}
	if(mm()->hasDataMask(MeshModel::MM_CAMERA) )      {info.append("MC ");}
	if(mm()->hasDataMask(MeshModel::MM_POLYGONAL) )   {info.append("MP ");}

	return info;
}
*/

CMeshModel::CMeshModel( const char* fullFileName/* = 0*/, const char* labelName/* = 0*/ )
{
	Clear();

	if( fullFileName )
		fullPathFileName = fullFileName;

	if( labelName )
		_label = labelName;
}

void CMeshModel::Clear()
{
	currentDataMask = MM_NONE;
    currentDataMask |= MM_VERTCOORD | MM_VERTNORMAL | MM_VERTFLAG ;
    currentDataMask |= MM_FACEVERT  | MM_FACENORMAL | MM_FACEFLAG ;

	cm.Tr.SetIdentity();
	cm.sfn=0;
	cm.svn=0;
}

void CMeshModel::Enable(int openingFileMask)
{
	if( openingFileMask & tri::io::Mask::IOM_VERTTEXCOORD )
		UpdateDataMask(MM_VERTTEXCOORD);
	if( openingFileMask & tri::io::Mask::IOM_WEDGTEXCOORD )
		UpdateDataMask(MM_WEDGTEXCOORD);
	if( openingFileMask & tri::io::Mask::IOM_VERTCOLOR    )
		UpdateDataMask(MM_VERTCOLOR);
	if( openingFileMask & tri::io::Mask::IOM_FACECOLOR    )
		UpdateDataMask(MM_FACECOLOR);
	if( openingFileMask & tri::io::Mask::IOM_VERTRADIUS   ) 
		UpdateDataMask(MM_VERTRADIUS);
	if( openingFileMask & tri::io::Mask::IOM_CAMERA       ) 
		UpdateDataMask(MM_CAMERA);
	if( openingFileMask & tri::io::Mask::IOM_VERTQUALITY  ) 
		UpdateDataMask(MM_VERTQUALITY);
	if( openingFileMask & tri::io::Mask::IOM_FACEQUALITY  ) 
		UpdateDataMask(MM_FACEQUALITY);
	if( openingFileMask & tri::io::Mask::IOM_BITPOLYGONAL ) 
		UpdateDataMask(MM_POLYGONAL);
}

bool CMeshModel::HasDataMask(const int maskToBeTested) const
{
	return ((currentDataMask & maskToBeTested)!= 0);
}

void CMeshModel::UpdateDataMask( CMeshModel *m )
{
	UpdateDataMask( m->currentDataMask );
}

void CMeshModel::UpdateDataMask(int neededDataMask)
{
	if((neededDataMask & MM_FACEFACETOPO)!=0)
	{
		cm.face.EnableFFAdjacency();
		tri::UpdateTopology<CMeshO>::FaceFace(cm);
	}
	if((neededDataMask & MM_VERTFACETOPO)!=0)
	{
		cm.vert.EnableVFAdjacency();
		cm.face.EnableVFAdjacency();
		tri::UpdateTopology<CMeshO>::VertexFace(cm);
	}

	if((neededDataMask & MM_WEDGTEXCOORD)!=0)  
		cm.face.EnableWedgeTexCoord();
	if((neededDataMask & MM_FACECOLOR)!=0)     
		cm.face.EnableColor();
	if((neededDataMask & MM_FACEQUALITY)!=0)   
		cm.face.EnableQuality();
	if((neededDataMask & MM_FACECURVDIR)!=0)   
		cm.face.EnableCurvatureDir();
	if((neededDataMask & MM_FACEMARK)!=0)	     
		cm.face.EnableMark();
	if((neededDataMask & MM_VERTMARK)!=0)      
		cm.vert.EnableMark();
	if((neededDataMask & MM_VERTCURV)!=0)      
		cm.vert.EnableCurvature();
	if((neededDataMask & MM_VERTCURVDIR)!=0)   
		cm.vert.EnableCurvatureDir();
	if((neededDataMask & MM_VERTRADIUS)!=0)    
		cm.vert.EnableRadius();
	if((neededDataMask & MM_VERTTEXCOORD)!=0)  
		cm.vert.EnableTexCoord();

	currentDataMask |= neededDataMask;
}

void CMeshModel::ClearDataMask(int unneededDataMask)
{
    if( ( (unneededDataMask & MM_VERTFACETOPO)!=0)	&& HasDataMask(MM_VERTFACETOPO)) 
	{
		cm.face.DisableVFAdjacency();
		cm.vert.DisableVFAdjacency(); 
	}
    if( ( (unneededDataMask & MM_FACEFACETOPO)!=0)	&& HasDataMask(MM_FACEFACETOPO))	
		cm.face.DisableFFAdjacency();
    if( ( (unneededDataMask & MM_WEDGTEXCOORD)!=0)	&& HasDataMask(MM_WEDGTEXCOORD)) 	
		cm.face.DisableWedgeTexCoord();
    if( ( (unneededDataMask & MM_FACECOLOR)!=0)			&& HasDataMask(MM_FACECOLOR))			
		cm.face.DisableColor();
    if( ( (unneededDataMask & MM_FACEQUALITY)!=0)		&& HasDataMask(MM_FACEQUALITY))		
		cm.face.DisableQuality();
    if( ( (unneededDataMask & MM_FACEMARK)!=0)			&& HasDataMask(MM_FACEMARK))			
		cm.face.DisableMark();
    if( ( (unneededDataMask & MM_VERTMARK)!=0)			&& HasDataMask(MM_VERTMARK))			
		cm.vert.DisableMark();
    if( ( (unneededDataMask & MM_VERTCURV)!=0)			&& HasDataMask(MM_VERTCURV))			
		cm.vert.DisableCurvature();
    if( ( (unneededDataMask & MM_VERTCURVDIR)!=0)		&& HasDataMask(MM_VERTCURVDIR))		
		cm.vert.DisableCurvatureDir();
    if( ( (unneededDataMask & MM_VERTRADIUS)!=0)		&& HasDataMask(MM_VERTRADIUS))		
		cm.vert.DisableRadius();
    if( ( (unneededDataMask & MM_VERTTEXCOORD)!=0)	&& HasDataMask(MM_VERTTEXCOORD))	
		cm.vert.DisableTexCoord();

    currentDataMask = currentDataMask & (~unneededDataMask);
}


int CMeshModel::io2mm(int single_iobit)
{
    switch(single_iobit)
    {
    case tri::io::Mask::IOM_NONE			: 
		return  MM_NONE;
    case tri::io::Mask::IOM_VERTCOORD		: 
		return  MM_VERTCOORD;
    case tri::io::Mask::IOM_VERTCOLOR		: 
		return  MM_VERTCOLOR;
    case tri::io::Mask::IOM_VERTFLAGS		: 
		return  MM_VERTFLAG;
    case tri::io::Mask::IOM_VERTQUALITY	: 
		return  MM_VERTQUALITY;
    case tri::io::Mask::IOM_VERTNORMAL		: 
		return  MM_VERTNORMAL;
    case tri::io::Mask::IOM_VERTTEXCOORD	: 
		return  MM_VERTTEXCOORD;
    case tri::io::Mask::IOM_VERTRADIUS		: 
		return  MM_VERTRADIUS;

    case tri::io::Mask::IOM_FACEINDEX   		: 
		return  MM_FACEVERT  ;
    case tri::io::Mask::IOM_FACEFLAGS   		: 
		return  MM_FACEFLAG  ;
    case tri::io::Mask::IOM_FACECOLOR   		: 
		return  MM_FACECOLOR  ;
    case tri::io::Mask::IOM_FACEQUALITY 		: 
		return  MM_FACEQUALITY;
    case tri::io::Mask::IOM_FACENORMAL  		: 
		return  MM_FACENORMAL ;
    case tri::io::Mask::IOM_WEDGTEXCOORD 		: 
		return  MM_WEDGTEXCOORD;
    case tri::io::Mask::IOM_WEDGCOLOR			: 
		return  MM_WEDGCOLOR;
    case tri::io::Mask::IOM_WEDGNORMAL   		: 
		return  MM_WEDGNORMAL  ;

    case tri::io::Mask::IOM_BITPOLYGONAL   	: 
		return  MM_POLYGONAL  ;

    default:
        assert(0);
        return MM_NONE;  // FIXME: Returning this is not the best solution (!)
        break;
    } ;
}